package com.coolxiaoyao.web.handler;

import com.coolxiaoyao.common.exception.HttpBadRequestException;
import com.coolxiaoyao.common.exception.HttpMethodNotAllowException;
import com.coolxiaoyao.common.exception.HttpNotFoundException;
import com.coolxiaoyao.common.exception.UnsupportedMediaTypeException;
import com.coolxiaoyao.common.http.ExceptionHandler;
import com.coolxiaoyao.common.inner.DefaultResponseBody;
import com.coolxiaoyao.web.http.MediaType;
import com.coolxiaoyao.web.inner.DefaultResponseFactory;
import com.coolxiaoyao.web.util.SerializationUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import io.netty.buffer.Unpooled;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.util.CharsetUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationTargetException;

import static com.coolxiaoyao.web.config.SupportConfig.SUPPORT_HTTP_VERSION;

/**
 * @author KerryZhang
 * <p>
 * 默认异常处理器
 */
public class DefaultExceptionHandler implements ExceptionHandler<DefaultFullHttpResponse> {

    private static final Logger logger = LoggerFactory.getLogger(DefaultExceptionHandler.class);

    @Override
    public DefaultFullHttpResponse onThrowable(Throwable throwable) {

        logger.error(throwable.getMessage(), throwable);

        // 默认500
        HttpResponseStatus status;


        if (throwable instanceof InvocationTargetException) {
            // 400
            status = HttpResponseStatus.BAD_REQUEST;
        } else if (throwable instanceof HttpBadRequestException) {
            // 400
            status = HttpResponseStatus.BAD_REQUEST;
        } else if (throwable instanceof HttpMethodNotAllowException) {
            // 405
            status = HttpResponseStatus.METHOD_NOT_ALLOWED;
        } else if (throwable instanceof UnsupportedMediaTypeException) {
            // 415
            status = HttpResponseStatus.UNSUPPORTED_MEDIA_TYPE;
        } else if (throwable instanceof HttpNotFoundException) {
            status = HttpResponseStatus.NOT_FOUND;
        } else {
            // 500 default
            status = HttpResponseStatus.INTERNAL_SERVER_ERROR;
        }

        DefaultFullHttpResponse response = new DefaultFullHttpResponse(SUPPORT_HTTP_VERSION, status);

        DefaultResponseBody defaultResponseBody = DefaultResponseFactory.create(throwable, status);
        String resultData;
        try {
            resultData = SerializationUtil.toJson(defaultResponseBody);
            response.headers().add(HttpHeaderNames.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE);
        } catch (JsonProcessingException e) {
            resultData = SerializationUtil.toJsonOrString(defaultResponseBody);
            response.headers().add(HttpHeaderNames.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE);
        }
        response.content().writeBytes(Unpooled.copiedBuffer(resultData, CharsetUtil.UTF_8));
        return response;
    }
}
